home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Cream of the Crop 25
/
Cream of the Crop 25.iso
/
program
/
flip3206.zip
/
FLIP32_A.ASM
< prev
next >
Wrap
Assembly Source File
|
1997-03-23
|
9KB
|
214 lines
;----------------------------------------------------------------------------
; FLIP32_A.ASM copyright (c) 1996-97, Xavier Defrang (aka brioche)
;----------------------------------------------------------------------------
; 32-bit protected mode FLI player
;----------------------------------------------------------------------------
; here are some great routines that does some great stuff... enjoy! :)
;----------------------------------------------------------------------------
; e-mail: 106146.1452@compuserve.com
;----------------------------------------------------------------------------
FLI_COLOR_ID equ 000bh ; some chunk magic numbers
FLI_LC_ID equ 000ch
FLI_BLACK_ID equ 000dh
FLI_BRUN_ID equ 000fh
FLI_COPY_ID equ 0010h
SCREEN_WIDTH equ 320 ; FLI's are always 320x200
SCREEN_HEIGHT equ 200
SCREEN_SIZE equ SCREEN_WIDTH*SCREEN_HEIGHT
PWA equ 03c8h ; Pixel Write Address
ISR1 equ 03dAh ; Input Status Register 1
VIDEO_MEM equ 0a0000h ; video memory physical addr
.386p
.model flat
;----------------------------------------------------------------------------
data segment public use32 ; don't need any data but...
data ends
;----------------------------------------------------------------------------
code segment public use32
assume cs:code, ds:data
public vmode ; setup bios video mode
public flip32_wait ; wait x jiffies (vbl sync.)
public flip32_unpack ; unpack a frame into a buf
;----------------------------------------------------------------------------
vmode proc near ; hum... does it really need
; to be commented? :)
int 10h ; eax = vid_mode_number
ret
vmode endp
;----------------------------------------------------------------------------
flip32_wait proc near ; using timer is better...
; ...but time is money! :)
or ecx, ecx
jz go_ahead ; if ( ecx == 0 ) exit
mov dx, ISR1
in_display: in al, dx ; wait for vbl (≈1/70s)
test al, 00001000b
jnz in_display
in_retrace: in al, dx
test al, 00001000b
jz in_retrace
dec ecx
jnz in_display ; loop...
go_ahead: ret
flip32_wait endp
;----------------------------------------------------------------------------
flip32_unpack proc near
push ebp
mov ebp, esp
arg src : dword, dst : dword, chunks : dword
;-- i'm sure i could optimize the way o send the params
;-- to this proc... pfff... so lazy! :)
mov esi, src ; [esi] = packed frame data
nextchunk: cmp chunks, 0 ; is it done for this frame?
je exit
dec chunks
mov ax, word ptr [esi+4] ; get frame magic number...
add esi, 6
cmp ax, FLI_COLOR_ID ; and jump to the right place!
je fli_color
cmp ax, FLI_LC_ID
je fli_lc
cmp ax, FLI_BLACK_ID
je fli_black
cmp ax, FLI_BRUN_ID
je fli_brun
cmp ax, FLI_COPY_ID
je fli_copy
jmp nextchunk ; burp... next one please!
;-- process fli_color chunk -------------------------------------------
fli_color: mov bx, word ptr [esi] ; get packets in chunk
add esi, 2
xor ax, ax ; start at color index 0
xor ecx, ecx
color_packloop: or bx, bx ; finish with packets?
jz nextchunk
dec bx
add al, byte ptr [esi] ; get color to start from
mov dx, PWA
out dx, al ; send it to the DAC
inc dl ; dx = Pixel Color Value reg
mov cl, byte ptr [esi+1] ; get # of colors that change
or cl, cl ; null?
jnz color_skip
inc ch ; 0 means 256
color_skip: add al, cl ; set color to restart from
lea ecx, [ecx+ecx*2] ; multiply by 3 (tricky! uh?)
add esi, 2
rep outsb ; set palette
jmp color_packloop ; process next color packet
;-- process fli_lc chunk -------------------------------------------
fli_lc: movzx edi, word ptr [esi] ; get start row
lea edi, [edi+edi*4] ; edi *= 5
shl edi, 6 ; edi *= 64 (note: 5*64=320!)
add edi, dst ; edi += dest_address
mov bx, word ptr [esi+2] ; get # lines that change
add esi, 4
xor ecx, ecx ; clear counter
lc_lineloop: or bx, bx
jz nextchunk ; check line counter...
dec bx
push edi ; save start row offset
mov dl, byte ptr [esi] ; get # of packets in line
inc esi
lc_packloop: or dl, dl
jz lc_nextline ; check packet counter
dec dl
mov cl, byte ptr [esi] ; bytes to skip
add edi, ecx
mov cl, byte ptr [esi+1] ; bytes that we gonna update
or cl, cl
jns lc_copy ; if positive then copy...
neg cl
mov al, byte ptr [esi+2]
add esi, 3
rep stosb ; fill with the same byte
jmp lc_packloop
lc_copy: add esi, 2
rep movsb ; copy bytes from src to dst
jmp lc_packloop
lc_nextline: pop edi ; restore start row offset...
add edi, SCREEN_WIDTH ; ...and jump to next line!
jmp lc_lineloop
;-- process fli_black chunk (a pretty hard one! :)) ---------------
fli_black: mov edi, dst ; load target address
mov ecx, SCREEN_SIZE/4 ; set up counter
xor eax, eax ; we gonna fill with null
rep stosd ; fill it!
jmp nextchunk
;-- process fli_brun chunk -----------------------------------
fli_brun: mov edi, dst ; we begin from dst...
mov bx, SCREEN_HEIGHT ; we update the whole screen
xor cx, cx
brun_lineloop: push edi ; save start row address
mov dl, byte ptr [esi] ; packet in line
inc esi
brun_packloop: or dl, dl
jz brun_nextline ; check packet counter
dec dl
mov cl, byte ptr [esi] ; bytes to write
or cl, cl
js brun_copy ; if negative then copy
mov al, byte ptr [esi+1]
add esi, 2
rep stosb ; fill with the same byte
jmp brun_packloop
brun_copy: neg cl
inc esi
rep movsb ; copy from src to dst...
jmp brun_packloop
brun_nextline: pop edi ; get back start row offset
add edi, SCREEN_WIDTH ; we go to the next line
dec bx
jnz brun_lineloop ; we will process next line
jmp nextchunk
;-- process fli_copy chunk -------------------------------------------
fli_copy: mov edi, dst ; pfff... a difficult one!
mov ecx, SCREEN_SIZE/4
rep movsd ; copy 320*200 screen
jmp nextchunk
exit: mov esp, ebp
pop ebp
ret
flip32_unpack endp
;----------------------------------------------------------------------------
code ends
end